Internet Newsgroups: comp.lang.basic.visual,comp.answers,news.answers Subject: comp.lang.basic.visual VB/Win Frequently Asked Questions X-Content-Currency: This FAQ changes regularly. When a saved or printed copy is over 6 months old, please obtain a new one. Expires: Sun, 8 May 1994 05:30:35 GMT Organization: Visual Basic FAQ Maintainers Date: Thu, 21 Apr 1994 05:30:42 GMT X-Posting-Frequency: Posted on the 5th and 20th of each month. Summary: Frequently asked questions concerning Visual Basic for Windows. Keywords: FAQ VISUAL BASIC WINDOWS VISUAL BASIC FOR WINDOWS (VB/Win) Commonly asked Questions & Answers Section IX - B ------------------------------------ TABLE OF CONTENTS: ------------------ PREFACE A - GENERAL VISUAL BASIC QUESTIONS 1 Does VB/Win make standalone .EXE files? 2 What is the current version of the Visual Basic? 3 Where can I get updated VB and other Microsoft files? 4 Where can I get good up-to-date information about VB? 5 Are there any examples of commercial applications built using Visual Basic? B - COMMON VISUAL BASIC PROGRAMMING QUESTIONS 1 What's the difference between MODAL and MODELESS forms? 2 When/Why should I use Option Explicit? 3 Is the Variant type slower than using other variable types? 4 How do I make a text box not beep when I hit the enter key? 5 How do I get the Tab key to be treated like a normal character? 6 What is passing by reference? 7 Is there any way to pass a variable to a form apart from using global variables? 8 How should dates be implemented so they work with other languages/countries formats? 9 Can a VB application be an OLE server? 10 How do I dial a phone number using the MSCOMM VBX in VB Pro? 11 I have [several] megabytes of memory. Why do I get an out of memory error? 12 How do I mimic a toggle button? 13 How do I get my application on top? C - ADVANCED VISUAL BASIC PROGRAMMING ISSUES 1 How do I tell when an application executed using the SHELL command is finished? 2 How do I access C style strings? 3 How can I change the printer Windows is using in code without using the print common dialog? 4 I'm adding lots of features to a LISTBOX, but it's sloooooow. What can I do to speed it up? 5 How do you make a TEXTBOX read only?. Or, how do I prevent the user from changing the text in a TEXTBOX? 6 How much gain in performance will I gain if I write my number crunching routines in C instead of in basic? 7 How can I create a VBX? 8 How do you change the system menu (on the Control-Menu Box)? 9 How do I play MID, WAV or other multimedia files? 10 How can I call a 'hidden' DOS program from VB? 11 How do I do drag & drop between applications? 12 How do I use GetPrivateProfileString to read from INI files? 13 How do I speed up control property access? 14 How do I implement Undo? 15 How do I create a window with a small title bar as in a floating toolbar? D - CALLING THE WINDOWS API AND DLLs IN GENERAL 1 What is the Windows API? 2 How do I call a DLL? 3 What about DLL calls that require callbacks? 4 Tips for calling DLLs (such as the Windows API) E - VISUAL BASIC AND DATABASES 1 Why can't I use an index with my VB accessed database? 2 Why does my compiled VB database app generate an error when it ran just fine in the design environment? 3 Is the Access Engine and Visual Basic Pro good enough for database work? 4 How do you avoid the "Invalid use of null" error when reading null values from a database? F - DISTRIBUTING VISUAL BASIC APPLICATIONS 1 What are some tips for using Setup Wizard? 2 Are there restrictions on what I can distribute with my VB program? G - MISCELLANEOUS TIPS AND INFORMATION 1 "Clean up" your project before compiling. 2 Multiple END statements can be dangerous. 3 What are the latest versions of the various files used by VB? PREFACE ------- This document is a compilation of frequently asked questions and their answers about Visual Basic for Windows which have been gathered from posts to the comp.lang.basic.visual newsgroup. Although some efforts have been made to find obvious errors, there is no guarantee that the information in this document is error-free. The FAQ maintainer, or anyone else associated with this document, assume NO liability for the content or use of this document. If you find any errors, please report them to the address given below. In this document, whenever a long line of code must be split into two or more lines of text in the code examples, a | symbol will precede each line which should be appended to the line above it. Most FAQs (including this one) are available at the anonymous ftp archive site "rtfm.mit.edu". All four parts of the VB FAQ may be found in the directory "pub/usenet/comp.lang.basic.visual". You can also have the VB FAQs e-mailed to you by sending a message to "mail-server@rtfm.mit.edu" with ONLY the text "send usenet/comp.lang.basic.visual/*" in the body of the message. A - GENERAL VISUAL BASIC QUESTIONS ---------------------------------- 1 Does VB/Win make standalone .EXE files? VB/Win produces .exe files, but they are not standalone. All VB/Win programs distributed must be with the VBRUNx00.DLL file. This DLL must accompany all VB/Win programs. 2 What is the current version of the Visual Basic? VB/Win is currently at version 3.0 3 Where can I get updated VB and other Microsoft files? Microsoft Software Library (MSL) is accessible from the following services: - CompuServe GO MSL Search for - Microsoft Download Service (MSDL) Dial (206) 936-6735 to connect to MSDL - Internet (anonymous FTP) ftp ftp.microsoft.com Change to the \softlib\mslfiles directory (There are a LOT of files in this directory! It is not advisable to list all the files.) 4 Where can I get good up-to-date information about VB? If you do any VB programming at all, you really should get the latest copy of the Microsoft Knowledge Base from one of the sources listed above! The filename is VBKB.EXE or VBKB_FT.EXE for the version with full text searching. The Knowledge Base is a Windows help formatted document that is updated almost monthly. This FAQ is a pretty good source as a digest of many of the VB issues that are discussed in the comp.lang.basic.visual newsgroup, but as such the information contained in this FAQ has not been thoroughly tested or verified. Dave McCarter puts out a nice Windows help formatted document called "Visual Basic Tips and Tricks". A good that isn't found in the Knowledge Base. It can be found at ftp.cica.indiana.edu /pub/pc/win3/programr/vbasic/ as VBTIPS??.ZIP, where '??' is the version number (yes, get the one with the highest number). There is presently an effort to put together a VB code library so that VB users can share their best - and trickiest - programming work. The code library project is being spear headed by Hein Ragas who has managed to get a directory on CICA for code snippets to be deposited. Stayed tuned to comp.lang.basic.visual for more information. 5 Are there any examples of commercial applications built using Visual Basic? Profit by Microsoft was written mostly in Visual Basic. In fact, Profit was one of three programs recently selected as PC Magazine's Editor's Choice among Windows small business accounting packages. B - COMMON VISUAL BASIC PROGRAMMING QUESTIONS --------------------------------------------- 1 What's the difference between MODAL and MODELESS forms? a MODAL forms are forms which require user input before any other actions can be taken place. In other words, a modal form has exclusive focus until it is dismissed. When showing a modal form, the program pauses at the SHOW command until the modal form is either hidden or unloaded. The internal MSGBOX and INPUTBOX$ forms are examples of modal forms. To show a form modally, use the syntax: MyForm.SHOW 1 b MODELESS forms are those which are shown but do not require immediate user input. Most child forms (in a MDI application) are typically modeless. To show a form modeless, use the syntax: MyForm.SHOW 2 When/Why should I use Option Explicit? Option Explicit forces you to declare all variables before using them. Opinions vary greatly on this subject. The main reason to use the OPTION EXPLICIT statement at the top of all modules is to minimize the amount of bugs introduced into your code by misspelling a variable name. Most variants of BASIC (including VB) have the capability to create variables 'on the fly' (without any declarations). This capability can be a double edged sword. At the minimum, it is suggested to use the DEFINT A-Z statement in leu of OPTION EXPLICIT. This statement will cause any variables which are created on the fly to be created as integers as opposed to single precision. (Integers take up less memory). The OPTION EXPLICIT statement causes VB to 'disable' it's ability to create variables on the fly. Thus, all variables must be declared using a DIM or REDIM statement. All variables not declared will cause an error when the OPTION EXPLICIT statement is used. This will eliminate any bugs when a variable is misspelled. 3 Is the Variant type slower than using other variable types? Generally, yes. The Variant variable type also increases memory overhead. To test the speed difference, try the following piece of code in something like a button_click event: Dim Va As Variant Dim In As Integer T1! = Timer For i% = 1 To 32766 Va = i% Next i% T2! = Timer Debug.Print "With variant: "; Format$((T2! - T1!), |"0.0000") T1! = Timer For i% = 1 To 32766 In = i% Next i% T2! = Timer Debug.Print "With integer: "; Format$((T2! - T1!), |"0.0000") This test shows (on our test system) that integers are ~60% faster! However, for strings there where no real difference, or in some instances, variants were faster than strings for routines with heavy conversion usage. For the best result in your application, test your routines directly. 4 How do I make a text box not beep when I hit the enter key? Put "something else" in your _KeyPress event, depending on what you really want. This code example makes *nothing* happen, for an extended period of time: Sub Text1_KeyPress (KeyAscii As Integer) If KeyAscii = 13 Then '13 is Key_Return KeyAscii = 0 '0 (zero) is nothing End If End Sub This might not be a very nice thing to do, since your users usually have some intention when they press Enter. Usually they will want to jump to the next control, like the Tab key does. To have the enter key emulate the Tab key action, you will need to change the line 'KeyAscii=0' to 'SendKeys "{tab}"' in the example above. By the way, you'll also find this in the Microsoft VB Knowledge Base (see KB Q85562 ?). You also be sure to set the MultiLine property to False, of course. 5 How do I get the Tab key to be treated like a normal character? You must set TabStop = False for ALL controls on the active form. Then you will be able to insert "tab" characters in controls like the text box. If you feel you need the Tab key to behave "normal" outside one specific control, it is trivial to emulate its functionality in code: Sub Command1_KeyDown (KeyCode As Integer, Shift As Integer) If KeyCode = 9 Then If Shift = 0 Then Command2.SetFocus 'Tab=Next control ElseIf Shift = 1 Then Command3.SetFocus 'Shift-Tab=Previous |control End If End If End Sub 6 What is passing by reference? Arguments are either passed by reference or by value. When they are passed by value, they cannot be changed by the procedure/function they are passed to. They *can* be altered when passed by reference, since passing by reference is just passing the address. Also note the following nasty trap: Arguments are passed by reference unless enclosed by parentheses or declared using the ByVal keyword. [VBWin Language Ref., p. 55] 7 Is there any way to pass a variable to a form apart from using global variables? While we wait for Microsoft to correct this annoying shortcoming, here's a nice "quick & dirty" method: The standard workaround is to put an invisible text box (or caption or any other control that suits your use.) on the target form and access it by Form.textbox = "value". Then you can use the Change event of that control to do anything you want in that form. Also, check out the .Tag property which is a "what-you-want" property where you can hook any string you want onto a control. This property can also be accessed from other modules. [Dave Mitton (mitton@dave.enet.dec.com)] 8 How should dates be implemented so they work with other languages/countries formats? If you use MM/DD/YY format dates in a program, you will get either a runtime-error (ie. month>12) or the wrong date (ie. March 12 instead of December 3) when your program is used in Europe. And vice versa, of course. Even Microsoft's own example programs (like the MAPI sample) make this stupid mistake. Use the Format command to make sure you get the date you want. For example: strTodaysDate = Format[$](Now, "Short Date") As a side note, Microsoft has taken much heat on the newsgroup for VB's bad support for Internationalization! 9 Can a VB application be an OLE server? No. You'll have to use an external DLL/VBX. If you see any examples, please tell the newsgroup. 10 How do I dial a phone number using the MSCOMM VBX in VB Pro? The MSCOMM VBX is great for creating communication programs, but it's overkill for dialing a phone number. Try the following code: PhoneNumber$ = "(123) 456-7890" Open "COM2" For Output As #1 'or COM1 umber$ & Chr$(13) Close #1 11 I have [several] megabytes of memory. Why do I get an out of memory error? Unfortunately, Microsoft is more famous for memory barriers than anything else. This is a late descendant of the infamous 640K barrier that has been plaguing us for years. Although Windows allows the user to access several megabytes of memory, it uses two limited (64K) memory areas called User Heap and GDI Heap. Go to the Help|About box in Program Manager to see the percentage of free resources in the *most* exhausted heap. If these areas are exhausted, you are out of luck. VB programs are unfortunately rather greedy on these structures. Windows 4 is supposed to free us from this limitation... 12 How do I mimic a toggle button? The only "fix" we know for this problem is to use a picture or image control to mimic the action of a button or button3d control. You need two bitmaps, one for buttonup and one for buttondown. This is a kludge, we know. Look at the button bar used in the MDINOTE sample program supplied with VB for an example of this. 13 How do I get my application on top? Set "MyForm.ZOrder = 0". Warning: It is consider bad behavior for applications to elbow to the top without allowing the user to turn this option off. An appropriate use would be for a "splash screen" that comes up to pacify the user while the program is loading. C - ADVANCED VISUAL BASIC PROGRAMMING ISSUES -------------------------------------------- 1 How do I tell when an application executed using the SHELL command is finished? Shell() doesn't really return a task handle, it returns an instance handle. Any documentation that says otherwise is wrong. But never mind that; the answer to your question is to use the API call GetModuleUsage. 'Put this in the general declarations of your form/module Declare Function GetModuleUsage Lib "Kernel" (ByVal |hModule As Integer) As Integer 'Here's where you shell out to the other program intHandle = Shell("PROGRAM.EXE") Do While GetModuleUsage(intHandle) > 0 DoEvents Loop [Kenn Nesbitt, Microsoft Consulting Services (kennn@netcom.com)] 2 How do I access C style strings? Use the 'lstrlen' and 'lstrcpy' calls found in the Kernel DLL. 3 How can I change the printer Windows is using in code without using the print common dialog? You can change the printer the VB 3.0 Printer object is pointing to programmatically (without using the common dialogs). Just use the WriteProfileString API call and rewrite the [WINDOWS], DEVICE entry in the WIN.INI file! VB will instantly use the new printer, when the next Printer.Print command is issued. If you get the old printer string before you rewrite it (GetProfileString API call), you can set it back after using a specific printer. This technique is especially useful, when you want to use a FAX printer driver: Select the FAX driver, send your fax by printing to it and switch back to the normal default printer. [Hajo Schmidt (hajo@bwl.bwl.th-darmstadt.de)] It is recommended (and polite, as we're multitasking) to send a WM_WININCHANGE (&H1A) to all windows to tell them of the change. Also, under some circumstances the printer object won't notice that you have changed the default printer unless you do this. Declare Function SendMessage(ByVal hWnd As Integer, |ByVal wMsg As Integer, ByVal wParam As Integer, |lParam As Any) As Long Global Const WM_WININICHANGE = &H1A Global Const HWND_BROADCAST = &HFFFF ' Dummy means send to all top windows. ' Send name of changed section as lParam. lRes = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, |ByVal "Windows") [Nic Gibson (nic@skin.demon.co.uk)] 4 I'm adding lots of features to a LISTBOX, but it's sloooooow. What can I do to speed it up? The basic problem with listboxes is that VB forces a repaint every time you call AddItem. You can get around this by switching off painting and then using LB_ADDSTRING messages to add items. If you want a code sample mail me and I'll get one from one of our apps. [Nic Gibson (nic@skin.demon.co.uk)] 5 How do you make a TEXTBOX read only?. Or, how do I prevent the user from changing the text in a TEXTBOX? There's a lot of ideas on this one. You can grab the _KeyPress and _KeyDown events and set them to zero. However, the best idea is to use the Windows API SendMessage function to tell the control to become read-only: 'After making the following declarations... Global Const WM_USER = &H400 Global Const EM_SETREADONLY = (WM_USER + 31) Declare Function SendMessage Lib "User" (ByVal hWnd As |Integer ByVal wMsg As Integer, ByVal wParam As |Integer, lParam As Any) As Long 'Then Try: SendMessage(Text1.hWnd, EM_SETREADONLY, 1, 0) [Pete Jones (pjones@csi.compuserve.com)] 6 How much gain in performance will I gain if I write my number crunching routines in C instead of in basic? Probably the best solution to the number crunching problem is to write the number crunching routines as a custom control or a DLL, and plug it into a VB app. VB interface handling is not significantly slower than, say C++, and most of the wait is associated with Windows. Some real world experience speaks volumes about this one: I wrote some time consuming code in VB to solve a combinatorical (does this word exist in English?) problem. The code consists of one main recursive function, which calls itself very often. It took a night to compute a certain problem. I was rather disappointed and then decided to write the central routine in C++. It was a 1:1 transcription. The routine was compiled with the MS C++-Compiler. It took only 22 Minutes for the same problem. Amazing, isn't it? The routine doesn't do any floating point arithmetic, only integer, and handles some arrays. The PC was a 33MHz 486. And the second amazing thing is, that a IBM RS6000 (560)-Risc-machine needed 17 Min for the same code. I was the only one on the machine. I though, it should be much faster. The MS C++ seems to make very fast, optimized code. The optimization was configured to make fast code. [Christoph Steinbeck (steinbeck@uni-bonn.de)] 7 How can I create a VBX? VBXs are usually written is C (Borland, VC++). You should refer to the _Control Development Guide_ (in VB Professional Features Vol. I) and any relevant documentation for your compiler. Followup questions should be directed to comp.lang.c.*. 8 How do you change the system menu (on the Control-Menu Box)? You can turn off the minimize and maximize menu options by changing properties, but what if you're doing something critical in your VB program that should not be interrupted and you need to remove the "close" option? 'Make the following declares. Declare Function GetSystemMenu Lib "User" (ByVal hWnd |As Integer, ByVal bRevert As Integer) As Integer Declare Function RemoveMenu Lib "User" (ByVal hMenu |As Integer, ByVal nPosition As Integer, ByVal wFlags As |Integer) As Integer Global Const MF_BYPOSITION=&H400 'Use the following code to remove the "close" option. SystemMenu% = GetSystemMenu (hWnd, 0) Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION) Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION) 'also remove the separator line Check out the GetMenuID and InsertMenu API functions to 9 How do I play MID, WAV or other multimedia files? Use the MSMCI.VBX, provided with VB/Win Pro 3.0. You can also declare and call the MM-functions manually: Declare Function mciExecute Lib "MMSystem" |(ByVal FileName as String) As Integer Sub Form1_Click () iResult = mciExecute("Play c:\windows\mkmyday.wav") End Sub 10 How can I call a 'hidden' DOS program from VB? If you run a DOS program minimized using the SHELL command, it will never return control to your VB program. This is because DOS tasks by default are NOT setup to run in the background. The easiest way to get around this is to make a PIF file for the program you need to run with the "Background" option checked. Then SHELL to the PIF file to run the DOS program and it will return control to your VB application when it terminates. 11 How do I do drag & drop between applications? Get the file FMDROP10.ZIP from ftp.cica.indiana.edu in the vbasic directory. It is a good VB example of drag & drop. You may also want to get the MSGBLAST VBX (3- 64.ZIP at ftp.microsoft.com in the MSDN directory) since you will need to have access to Windows messages in order to do drag & drop - unless you get a VBX to do it for you. Also, the D&DSERVE example from Windows Tech Journal Aug 92 includes a DLL for this purpose. This is available from some ftp sites. Drag & Drop Client: the form you drop objects to/on Drag & Drop Server: the form you drag object(s) from 12 How do I use GetPrivateProfileString to read from INI files? There's a good example of accessing *.INI files in the Knowledge Base, but here's the basic idea: 'You declare these API function as usual: Declare Function GetPrivateProfileString Lib "Kernel" |(ByVal lpApplicationName As String, ByVal lpKeyName |As Any, ByVal lpDefault As String, ByVal |lpReturnedString As String, ByVal nSize As Integer, |ByVal lpFileName As String) As Integer 'Then in your code you do like below: strIniFile = "WIN.INI" strSection = "MyProgram" strKey = "Language" strDefault = "English" iLength = 70 strReturn = String$(iLength, " ") 'Pad the string first! iResult = GetPrivateProfileString(strSection, strKey, |strDefault, strReturn, iLength, strIniFile) Also, be aware that there was an error in the Windows 3.1 API documentation that came with VB. Here's the scoop: Knowledge Base article q110826 (DOCERR: GetPrivateProfileString Declaration Incorrect in API corrects a documentation error for the GetPrivateProfileString function call as described in the Windows version 3.1 API Reference help file that shipped with Microsoft Visual Basic version 3.0 for Windows. The correct declaration is as follows: Declare Function GetPrivateProfileString Lib "Kernel" |(ByVal lpApplicationName As String, ByVal lpKeyName |As Any, ByVal lpDefault As String, ByVal |lpReturnedString As String, ByVal nSize As Integer, |ByVal lpFileName As String) As Integer Note that the "ByVal" keyword was omitted from the second parameter in the online reference. This means that the function is passing the second parameter (lpKeyName) by reference. It needs to be passed by value. The most common problem that occurs when using the incorrect declaration is that when the function is called, it returns a copy of "lpdefault" in the "lpReturnedString" parameter instead of the actual value referenced by KeyName. 13 How do I speed up control property access? Instead of using a property in a loop, you will be better off using a normal variable in the loop and then assign the variable once to the property afterwards. Also, when reading a property, you should read it once into a variable instead of using it in a loop. Sometimes it is not possible to simply put contents of a property into a variable. For example, if you are using a list box or you need to conserve memory. In these cases you can send the WM_SetRedraw message to the control to prevent redrawing. You can typically increase the speed 6-10 times - or even more. 'Add the following declares: Declare Function SendMessage Lib "User" (ByVal hWnd As |Integer, ByVal wMsg As Integer, ByVal wParam As |Integer, lParam As Any) As Long Const WM_SetRedraw = &HB 'Add this to your code: Result% = SendMessage(Text1.hWnd, WM_SetRedraw, 0, 0) 'redraw off 'Do your stuff here! Result% = SendMessage(Text1.hWnd, WM_SetRedraw, 1, 0) 'redraw on This same method applies to list boxes and other controls. 14 How do I implement Undo? For most controls, you will have to keep track of changes yourself. However, if you use the standard Text box or Combo box, Windows provides a "free" undo function for you! 'Do the following declares: Declare Function SendMessage Lib "User" (ByVal hWnd As |Integer, ByVal wMsg As Integer, ByVal wParam As |Integer, lParam As Any) As Long Global Const WM_USER = &h400 Global Const EM_UNDO = WM_USER + 23 'And in your Undo Sub do the following: UndoResult = SendMessage(myControl.hWnd, EM_UNDO, |0, 0) 'UndoResult = -1 indicates an error. 15 How do I create a window with a small title bar as in a floating toolbar? Download the MSGBLAST VBX from ftp.microsoft.com (filename "8-3.ZIP") or TBOX100.ZIP from ftp.cica.indiana.edu. These files provide an example of a form with a small title. When you see it, you'll understand why we haven't include a full explanation here! D - CALLING THE WINDOWS API AND DLLs IN GENERAL ----------------------------------------------- 1 What is the Windows API? The Windows API is a collection of Dynamic-Link Libraries (DLLs) that do most of the common things in Windows. Calls to the Windows API gives you access to routines that do things like drawing menu bars, manipulating bitmaps, playing sound files, and pretty much every other function of Windows. 2 How do I call a DLL? Basically, you declare a DLL procedure which you can call in your VB program which in turn passes data to and/or retrieves data from the DLL. You should read the section of the VB manual that talks about calling DLLs ("Chapter 24 Calling Procedures in DLLs" in the VB 3.0 Programmer's Guide). This chapter covers the basics of using the Windows API DLLs and calling DLLs in general. Beyond that you may want to find a good book on this subject since it is too large to cover here (see the Book Listing in the Appendix of the General FAQ - Part 1). Don't be too intimidated! Using DLLs (especially many of the Windows API functions) is quite easy, once you learn how to call them. In fact, many of the newer DLLs include VB-compatible modules! 3 What about DLL calls that require callbacks? Dan Appleman's "Visual Basic Programmer's Guide to the Windows API" comes with a floppy disk which code samples and tools. It also includes a VBX which supports the callbacks which many API calls require. Dan is also founder and president of Desaware which sells more extensive tools, including SpyWorks, for VB developers. [Walter Hill (whill@netcom.com)] 4 Tips for calling DLLs (such as the Windows API) a Using the BYVAL keyword is critical. Using it when you're supposed to call by reference and (more common) not using it when you are to give a value to the external function are the single most common mistakes. Wrong calling lt in a General Protection Fault (GPF) or, even worse, corruption of another applications data. b Check return and parameter types. For return types, a C function declared as "void" means you use a Sub not a Function. c Initialize strings! If you pass a string that is too short to the API it will happily write past the end of the string and possibly corrupt data. d Use Option Explicit. A typing error that results in a bug in the VB source will occasionally cause a GPF when you call external code. e It's a jungle out there. Check parameter values as there is no type checking outside VB. If you make a mistake, you'll often get a GPF. f Save before you run. You may even need to restart Windows after a GPF, since DLL's often aren't unloaded properly. E - VISUAL BASIC AND DATABASES ------------------------------ 1 Why can't I use an index with my VB accessed database? There is a mistake in the docs which says you can set the active index for a recordset. You can't. The data control uses the primay key for tables and physical order (I think) for dynasets. [Nic Gibson (nic@skin.demon.co.uk)] 2 Why does my compiled VB database app generate an error when it ran just fine in the design environment? You can thank Microsoft for documenting this topic so poorly. When you compile your VB database application, you must also have an INI file for it which provides the correct pointers to the appropriate database drivers. Therefore, if your application is named "INVOICE.EXE", you will need to have a properly configured "INVOICE.INI" file in your Windows directory. The file, EXTERNAL.TXT, that came with VB should explain all about it. 3 Is the Access Engine and Visual Basic Pro good enough for database work? That, of course, depends. Generally the answer is "yes", but you may need some third-party add-on products. These are the major weaknesses of VBPro's database functions: - Limited data controls: No add, delete or search button; no bound list box or masked edit control and - the worst - no bound grid! - No run-time query builder ("how good is your user in SQL?") or report builder. - No direct advanced control of the Access 1.1 Database Engine. The good news is that lots of companies are willing to sell you products which address one or more of the above weaknesses. Also, if you build a database application with advanced database relations, it can be a good idea to build the database with Access and the front-end with VB. 4 How do you avoid the "Invalid use of null" error when reading null values from a database? If you try to retrieve a null value (empty field) from a database, you will get the error: "Invalid use of Null". Here is one way to get around this problem: I've worked around this problem with the following code: TextBox.Text = MyTest.Fields("TestFld") & "" This code converts the Null-Value into an empty string. [Ralf Metzing (rmm@dragon.stgt.sub.org)] F - DISTRIBUTING VISUAL BASIC APPLICATIONS ------------------------------------------ 1 What are some tips for using Setup Wizard? a There were some bugs in the setup utilities supplied with VB. Be sure to get the newest version of SETUPKIT (usually called SETUPK.EXE or ZIP). It is available from the sources listed in Section VIII of the General FAQ (Part 1). Alternatively, if you have the older versions, you may have to manually remove the line referring to OLE2UI.DLL in the file SETUPWIZ.INI. Here is the latest information on the Setup Wizard files as of 4/94: File Current Size/Date Orginal Size/Date ------------ ----------------- ----------------- SETUP EXE 19,056 08-23-93 15,312 04-28-93 SETUP1 BAS 27,268 10-14-93 26,452 04-28-93 SETUP1 FRM 15,341 01-21-94 16,331 04-28-93 SETUP1 FRX 770 01-21-94 770 04-28-93 SETUPK TXT 16,933 03-07-94 n/a SETUPWIZ EXE 153,486 02-01-94 150,670 04-28-93 SETUPWIZ INI 3,844 02-18-94 3,638 04-28-93 Follow the instructions in SETUPK.TXT exactly. The files actually belong in two separate directories. Not placing them correctly can create strange and unusual side effects -- none of them good(!) b Set all involved EXE, DLL and CVX files to Read-Only so that the setup program doesn't modify them. [Charles F. Mulks (21667cfm@msu.edu)] 2 Are there restrictions on what I can distribute with my VB program? The documentation tells what parts of the Visual Basic kit you can freely distribute: the VBX files, some DLL's and what the SetupKit includes on your distribution diskettes. Reading software license agreements may be more boring than asking the newsgroup, but is nevertheless a good idea. 8^) There have been some rumors on the newsgroup that you can't redistribute programs written with VB freely. This is nonsense. All applications created with VB can be redistributed freely without royalties (as long as you don't distribute proprietary external files). The rumors probably originated when Microsoft announced that they will not sell kits allowing third-party software to include the Visual Basic for Applications (VBA) system. G - MISCELLANEOUS TIPS AND INFORMATION ------------------------------------- 1 "Clean up" your project before compiling. When you are ready to compile your VB project into your 'finished' EXE, be sure to save the project files, exit VB, run VB, load your project and go straight to compiling. Otherwise, your EXE will be larger in file size than necessary due to 'garbage' getting included in the EXE. For some reason, VB does not fully clean up all of the previously used variables or objects that you may have been playing with while developing your program so these get included in your EXE even though they aren't used. Other VB users have even advocated saving all the project files as ASCII, then loading the ASCII files before compiling to further "clean up" the resulting EXE file. 2 Multiple END statements can be dangerous. Suggestion: put the end statement used to exit your program *only* in the Form_Unload event of the main form. Whenever you want to end the program, just tell the main form to unload. 3 What are the latest versions of the various files used by VB? File to Updated Date Download Files Description --------------------------------------------------------------- 3/7/94 BTR110.EXE BTRV110.DLL Btrieve IISAM Driver 3/7/94 DATAINDX.EXE DATAINDX.DOC Index for the "Data Access Guide" 3/7/94 GENRIC.EXE \VB\CDK\GENERIC Sample custom control source code 3/7/94 VBGRID.EXE GRID.VBX Grid control 3/7/94 VBHC505.EXE HC.EXE and Standard and Protected HCP.EXE mode WinHelp Compiler 3/7/94 MSAJT.EXE MSAJT110.DLL Microsoft Access Database Engine 3/8/94 MSCOMM.EXE MSCOMM.VBX Serial Communications\ control 3/7/94 ORA110.EXE ORACLE.TXT Updated ORACLE.TXT file 3/7/94 SETUPK.EXE SETUP.EXE Setup Toolkit 3/7/94 VBRUN300.EXE VBRUN300.DLL Visual Basic Runtime Library 3/7/94 XBS110.EXE XBS110.DLL XBase IISAM Driver There is an article in the Microsoft Knowledge Base that points to each of these files and provides more detailed information about the update. To find these articles, query the Microsoft Knowledge Base using the file name and the word "update3.00".